package com.neusoft.yiyang.care.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.neusoft.yiyang.care.client.TaskClient;
import com.neusoft.yiyang.care.mapper.CareLevelItemMapper;
import com.neusoft.yiyang.care.mapper.CareRecordMapper;
import com.neusoft.yiyang.common.entity.care.CareItem;
import com.neusoft.yiyang.common.entity.care.CareLevelItem;
import com.neusoft.yiyang.common.entity.care.CareRecord;
import com.neusoft.yiyang.common.entity.care.CustomerCareItem;
import com.neusoft.yiyang.common.utils.OssUploadUtils;
import com.neusoft.yiyang.care.mapper.CareItemMapper;
import com.neusoft.yiyang.care.mapper.CustomerCareItemMapper;
import com.neusoft.yiyang.care.service.CustomerCareItemService;
import com.neusoft.yiyang.common.enums.ExecCycle;
import com.neusoft.yiyang.common.enums.ExecutionStatus;
import com.neusoft.yiyang.common.exception.BusinessException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.time.LocalDate;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

@Service
public class CustomerCareItemServiceImpl implements CustomerCareItemService {

    @Autowired
    private CustomerCareItemMapper customerCareItemMapper;

    @Autowired
    private CareItemMapper careItemMapper;

    @Autowired
    private CareLevelItemMapper careLevelItemMapper;

    @Autowired
    private CareRecordMapper careRecordMapper;

    @Autowired
    private TaskClient taskClient;

    @Autowired
    private OssUploadUtils ossUploadUtils;

    @Override
    public void addCustomerCareItem(CustomerCareItem customerCareItem) {
        customerCareItemMapper.insert(customerCareItem);
    }

    @Override
    public void updateCustomerCareItem(CustomerCareItem customerCareItem) {
        customerCareItemMapper.updateById(customerCareItem);
    }

    @Override
    public void deleteCustomerCareItem(Integer customerCareItemId) {
        customerCareItemMapper.deleteById(customerCareItemId);
    }

    // 根据护理等级为客户分配护理项目
    @Override
    @Transactional
    public void addCareItemsByCareLevel(Integer customerId, Integer careLevelId) {
        // 1. 物理删除客户原有的所有护理项目（彻底删除，避免唯一索引冲突）
        LambdaQueryWrapper<CustomerCareItem> deleteWrapper = new LambdaQueryWrapper<>();
        deleteWrapper.eq(CustomerCareItem::getCustomerId, customerId);
        customerCareItemMapper.delete(deleteWrapper); // 改为物理删除

        // 2. 查询该护理等级下的所有护理项目
        List<CareLevelItem> levelItems = careLevelItemMapper.selectListByCareLevelId(careLevelId);
        if (levelItems == null || levelItems.isEmpty()) return;

        // 3. 为客户添加新的护理项目（此时旧记录已物理删除，可安全插入）
        for (CareLevelItem levelItem : levelItems) {
            Integer careItemId = levelItem.getCareItemId();
            CareItem careItem = careItemMapper.selectById(careItemId);
            if (careItem == null || careItem.getStatus() != 1) continue; // 检查护理项目是否存在且启用

            CustomerCareItem customerCareItem = new CustomerCareItem();
            customerCareItem.setCustomerId(customerId);
            customerCareItem.setCareItemId(careItemId);
            customerCareItem.setCareLevelId(careLevelId);
            customerCareItem.setPurchaseDate(new Date());
            customerCareItem.setQuantityTotal(careItem.getExecCount() * 12); // 默认购买12个周期
            customerCareItem.setUsedCount(0);
            customerCareItem.setExpiryDate(calculateExpiryDate(careItem.getExecCycle(), 12));
            customerCareItem.setIsDeleted(0);

            customerCareItemMapper.insert(customerCareItem);
        }

        taskClient.handleCustomerUpdate(customerId);
    }

    // 完成护理记录并更新使用次数
    @Override
    @Transactional
    public void completeCareRecordWithUsageUpdate(
            Integer customerId, Integer careItemId, Integer caretakerId,
            Integer quantity, String feedback, ExecutionStatus status,
            MultipartFile file) { // 接收照片URL
        String photoUrl = null;
        if (file != null && !file.isEmpty()) {
            String folder = "care-photos/" + LocalDate.now();
            photoUrl = ossUploadUtils.uploadFile(file, folder);
        }
        // 1. 更新护理项目使用次数
        CustomerCareItem careItem = customerCareItemMapper.selectOne(
                new LambdaQueryWrapper<CustomerCareItem>()
                        .eq(CustomerCareItem::getCustomerId, customerId)
                        .eq(CustomerCareItem::getCareItemId, careItemId)
                        .eq(CustomerCareItem::getIsDeleted, 0)
        );
        if (careItem == null) {
            throw new BusinessException(4001, "护理项目不存在");
        }
        if (careItem.getUsedCount() + quantity > careItem.getQuantityTotal()) {
            throw new BusinessException(4002, "使用次数超过总量");
        }
        careItem.setUsedCount(careItem.getUsedCount() + quantity);
        customerCareItemMapper.updateById(careItem);
        // 2. 创建护理记录
        CareRecord record = new CareRecord();
        record.setCustomerId(customerId);
        record.setCareItemId(careItemId);
        record.setCaretakerId(caretakerId);
        record.setCareTime(new Date());
        record.setQuantity(quantity);
        record.setFeedback(feedback);
        record.setStatus(status);
        record.setPhotoUrl(photoUrl);
        careRecordMapper.insert(record);
    }

    // 获取有效的护理项目
    @Override
    public List<CustomerCareItem> getValidCareItemsByCustomerId(Integer customerId) {
        LambdaQueryWrapper<CustomerCareItem> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CustomerCareItem::getCustomerId, customerId)
                .eq(CustomerCareItem::getIsDeleted, 0)
                .ge(CustomerCareItem::getExpiryDate, new Date())
                .apply("quantity_total >= used_count");
        return customerCareItemMapper.selectList(wrapper);
    }

    // 计算到期日期
    private Date calculateExpiryDate(ExecCycle execCycle, Integer cycles) {
        Calendar calendar = Calendar.getInstance();
        switch (execCycle) {
            case daily:
                calendar.add(Calendar.DAY_OF_YEAR, cycles);
                break;
            case weekly:
                calendar.add(Calendar.WEEK_OF_YEAR, cycles);
                break;
            case monthly:
                calendar.add(Calendar.MONTH, cycles);
                break;
        }
        return calendar.getTime();
    }

}
